package com.zrrd.mcl.activity.receiver;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.rabbitmq.client.Channel;
import com.zrrd.mcl.activity.mapper.SeckillMapper;
import com.zrrd.mcl.activity.service.SeckillGoodsService;
import com.zrrd.mcl.common.util.DateUtil;
import com.zrrd.mcl.model.activity.SeckillGoods;
import com.zrrd.mcl.model.activity.UserRecode;
import com.zrrd.mcl.rabbit.constant.MqConstant;
import com.zrrd.mcl.service.constant.RedisConst;
import org.springframework.amqp.core.ExchangeTypes;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.Exchange;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.QueueBinding;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;


import java.util.Date;
import java.util.List;

@Component
public class SeckillReceiver {

    @Autowired
    private SeckillMapper seckillMapper;

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private SeckillGoodsService seckillGoodsService;

    //监听消息
    @RabbitListener(bindings = @QueueBinding(
            value = @Queue(value = MqConstant.QUEUE_TASK_1),
            exchange = @Exchange(value = MqConstant.EXCHANGE_DIRECT_TASK),
            key = {MqConstant.ROUTING_TASK_1}
    ))
    public void importDateToRedis(Message message, Channel channel) throws Exception {
        System.out.println("收到MQ消息====>");
        //查询审核状态为1  库存数量大于0  且是当天的商品
        QueryWrapper<SeckillGoods> wrapper = new QueryWrapper<>();
        wrapper.eq("status",1);
        wrapper.gt("stock_count",0);
        wrapper.eq("DATE_FORMAT(start_time,'%Y-%m-%d')", DateUtil.formatDate(new Date()));
        List<SeckillGoods> seckillGoods = seckillMapper.selectList(wrapper);
        System.out.println("查询当前的秒杀商品====>" + seckillGoods);
        if (!CollectionUtils.isEmpty(seckillGoods)) {
            //遍历集合
            for (SeckillGoods seckillGood : seckillGoods) {
                //如果redis中有该商品
                if (redisTemplate.boundHashOps(RedisConst.SECKILL_GOODS).hasKey(seckillGood.getSkuId().toString())) {
                    //本次循环不处理
                    continue;
                }
                //存入redis     大key===>seckill:goods 小key====>skuid   value====>秒杀商品对象
                redisTemplate.boundHashOps(RedisConst.SECKILL_GOODS).put(seckillGood.getSkuId().toString(), seckillGood);

                //根据每一个商品的库存数量循环
                for (Integer i = 0; i < seckillGood.getStockCount(); i++) {
                    //把每个商品的数量按照队列的形式存入Redis中
                    redisTemplate.boundListOps(RedisConst.SECKILL_STOCK_PREFIX + seckillGood.getSkuId()).leftPush(seckillGood.getSkuId().toString());
                }
                //更新状态位
                redisTemplate.convertAndSend("seckillpush", seckillGood.getSkuId() + ":1");

            }
        }
        //手动回执确认
        channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);

    }

    //监听消息--->将秒杀用户加入队列
    @RabbitListener(bindings = @QueueBinding(
            value = @Queue(value = MqConstant.QUEUE_SECKILL_USER,durable = "true"),
            exchange = @Exchange(value = MqConstant.EXCHANGE_DIRECT_SECKILL_USER,type = ExchangeTypes.DIRECT,durable = "true"),
            key = {MqConstant.ROUTING_SECKILL_USER}
    ))
    public void seckill(UserRecode userRecode,Message message,Channel channel) throws Exception{
        if(userRecode != null){
            System.out.println("收到消息====>" + userRecode);
            System.out.println("开始预约下单====>");
            //预约下单
            seckillGoodsService.seckillOrder(userRecode.getSkuId(),userRecode.getUserId());
            //手动回执
            channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
        }
    }

    //监听消息---->秒杀结束 清除缓存
    @RabbitListener(bindings = @QueueBinding(
            value = @Queue(value = MqConstant.QUEUE_TASK_18),
            exchange = @Exchange(value = MqConstant.EXCHANGE_DIRECT_TASK),
            key = {MqConstant.ROUTING_TASK_18}
    ))
    public void clearCache(Message message,Channel channel) throws Exception{
        //查询Mysql中当天的秒杀商品
        QueryWrapper<SeckillGoods> wrapper = new QueryWrapper<>();
        wrapper.eq("status",1);
        wrapper.ge("end_time",new Date());
        List<SeckillGoods> seckillGoods = seckillMapper.selectList(wrapper);
        for (SeckillGoods seckillGood : seckillGoods) {
            //清理Redis中队列的秒杀商品
            redisTemplate.delete(RedisConst.SECKILL_STOCK_PREFIX+seckillGood.getSkuId());
        }
        //清除Redis中存入的秒杀商品
        redisTemplate.delete(RedisConst.SECKILL_GOODS);
        redisTemplate.delete(RedisConst.SECKILL_ORDERS);
        redisTemplate.delete(RedisConst.SECKILL_ORDERS_USERS);
        //将Mysql的对应的秒杀商品状态改为2
        SeckillGoods goods = new SeckillGoods();
        goods.setStatus("2");
        seckillMapper.update(goods,wrapper);
        //收订确认消息回执
        channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
    }

}
